#ifndef ENGINE_H
#define ENGINE_H

#include <QThread>
#include <QMap>
#include <QSharedPointer>
#include <QMutex>
#include <QWaitCondition>
#include <QImage>
#include <piocore.h>
#include <mediaitem.h>

class Engine : public QThread
{
    Q_OBJECT
public:
    enum SizeMode {
        CropImage,
        ShrinkImage,
        MatchWidth,
        MatchHeight
    };

    explicit Engine(PioCore * core, QObject *parent = 0);
    virtual ~Engine();
    double itemWidth() { return m_item_width; }
    double itemHeight() { return m_item_height; }
    
signals:
    void changed();
    void completed(bool completed);
    
public slots:
    void enable(bool enable);
    void setAutoRotate(bool rotate);
    void setSizeMode(SizeMode mode);
    void setPrintMarkers(bool markers);
    void setItemWidth(double width);
    void setItemHeight(double height);
    void setSelection(QList<MediaItemPtr> selection);
    void print(class QPrinter * printer);

protected:
    virtual void run();
    
private:    
    struct ImageInfo {
        QImage image;
        QSize originalSize;
        SizeMode mode;
        bool rotate;
    };

    bool getFirstInvalidItem(MediaItem::Metadata & item);
    void getOperations(const QSize & originalSize, SizeMode & mode, bool & rotate);
    QList<QImage> takeRow(QList<QImage> & images, double width, double margin);
    double toCentimeters(int pixels);
    int toPixels(double centimeters);
    void printMarkers(QPainter & painter, const QRectF & rect);

    PioCore * m_core;

    // data
    QList<MediaItem::Metadata> m_selection;
    QMap<QString, ImageInfo> m_images;

    // synchronization
    QMutex m_mutex;
    QWaitCondition m_cond;
    bool m_quit;
    bool m_enabled;

    // options
    bool m_autorotate;
    double m_item_width;
    double m_item_height;
    SizeMode m_size_mode;
    bool m_markers;
};

#endif // ENGINE_H
